using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using WindowsLive.Writer.Api;
using DiggThis.Utils;
using WLWPluginBase.Utils;

namespace DiggThis.Forms
{
    /// <summary>
    /// Wrapper of <see cref="ISmartContent"/> properties used to describe the smart content definition for this plugin.
    /// </summary>
    public class DiggThisConfig
    {
        #region Fields
        /// <summary>
        /// Interface used to manipulate the state, layout, and supporting files of objects created by a <see cref="SmartContentSource"/> object.
        /// </summary>
        private readonly ISmartContent content;
        #endregion Fields

        #region Properties
        [XmlIgnore]
        public string ImgUrl
        {
            get { return content.Files.GetUri(ImgFilename).AbsolutePath; }
        }
        [XmlIgnore]
        public string ImgCompactUrl
        {
            get { return content.Files.GetUri(ImgCompactFilename).AbsolutePath; }
        }
        [XmlIgnore]
        public string ImgFilename
        {
            get { return content.Properties.GetString("ImgFilename", string.Empty); }
            set { content.Properties.SetString("ImgFilename", value); }
        }
        [XmlIgnore]
        public string ImgCompactFilename
        {
            get { return string.Format("_{0}", ImgFilename); }
        }
        public string Url
        {
            get { return content.Properties.GetString("Url", string.Empty); }
            set { content.Properties.SetString("Url", value); }
        }
        public string Title
        {
            get { return content.Properties.GetString("Title", string.Empty); }
            set { content.Properties.SetString("Title", value); }
        }
        public string Text
        {
            get { return content.Properties.GetString("Text", string.Empty); }
            set { content.Properties.SetString("Text", value); }
        }
        public string Topic
        {
            get { return content.Properties.GetString("Topic", string.Empty); }
            set { content.Properties.SetString("Topic", value); }
        }
        public string BkgColor
        {
            get { return content.Properties.GetString("BkgColor", string.Empty); }
            set { content.Properties.SetString("BkgColor", ColorUtil.IsValidColor(value) ? value : null); }
        }
        [XmlIgnore]
        public string Skin
        {
            get { return (Compact ? "compact" : string.Empty); }
        }
        public bool Compact
        {
            get { return content.Properties.GetBoolean("Compact", false); }
            set { content.Properties.SetBoolean("Compact", value); }
        }
        public Alignment TextWrapping
        {
            get { return content.Layout.Alignment; }
            set { content.Layout.Alignment = value; }
        }
        public bool CustomMargins
        {
            get { return content.Properties.GetBoolean("CustomMargins", false); }
            set { content.Properties.SetBoolean("CustomMargins", value); }
        }
        public int TopMargin
        {
            get { return content.Layout.TopMargin; }
            set { content.Layout.TopMargin = value; }
        }
        public int RightMargin
        {
            get { return content.Layout.RightMargin; }
            set { content.Layout.RightMargin = value; }
        }
        public int BottomMargin
        {
            get { return content.Layout.BottomMargin; }
            set { content.Layout.BottomMargin = value; }
        }
        public int LeftMargin
        {
            get { return content.Layout.LeftMargin; }
            set { content.Layout.LeftMargin = value; }
        }
        [XmlIgnore]
        public bool HasOptionalProperties
        {
            get
            {
                return !(string.IsNullOrEmpty(Url)
                    && string.IsNullOrEmpty(Title)
                    && string.IsNullOrEmpty(Text)
                    && string.IsNullOrEmpty(Topic)
                    && string.IsNullOrEmpty(BkgColor)
                    && string.IsNullOrEmpty(Skin));
            }
        }
        #endregion Properties

        #region Initialization
        /// <summary>
        /// Constructs a <see cref="DiggThisConfig"/> instance.
        /// </summary>
        /// <param name="content">Reference to object used to manipulate smart content propperties.</param>
        private DiggThisConfig(ISmartContent content)
        {
            this.content = content;
        }
        /// <summary>
        /// Initializes an instance of <see cref="DiggThisConfig"/> wrapping the given <see cref="ISmartContent"/> object.
        /// </summary>
        /// <param name="content">Reference to object used to manipulate smart content propperties.</param>
        /// <returns><see cref="DiggThisConfig"/> instance.</returns>
        public static DiggThisConfig GetInstance(ISmartContent content)
        {
            // We want to encapsulate the creation of the settings object in case we change its implementation
            // in future releases.
            return (new DiggThisConfig(content));
        }
        #endregion Initialization

        #region Persistence
        /// <summary>
        /// Default plugin configuration file name.
        /// </summary>
        [XmlIgnore]
        private static string ConfigFile
        {
            get { return (Assembly.GetExecutingAssembly().Location + ".config"); }
        }
        /// <summary>
        /// Load this plugin's configuration.
        /// </summary>
        /// <param name="content">Reference to the smart content instance representing this plugin.</param>
        /// <returns>The plugin's configuration data.</returns>
        public static DiggThisConfig Load(ISmartContent content)
        {
            // Create a default configuration instanace.
            DiggThisConfig settings = GetInstance(content);
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(DiggThisPersistableProperties));
                TextReader reader = new StreamReader(ConfigFile);
                DiggThisPersistableProperties ps = serializer.Deserialize(reader) as DiggThisPersistableProperties;
                if (ps != null)
                {
                    ps.ToDiggThisSettings(ref settings);
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                // Ignore errors while loading the configuration.
                Debug.Write(ex.Message);
            }
            // Return the result of the operation.
            return settings;
        }
        /// <summary>
        /// Store this plugin's configuration.
        /// </summary>
        public void Store()
        {
            // Delegate the call to the configuration utility.
            ConfigUtil.StoreConfig(ConfigFile, new DiggThisPersistableProperties(this));
        }
        #endregion Persistence

        #region Internal Classes
        /// <summary>
        /// Persistable properties used for this plugin's configuration.
        /// </summary>
        [XmlRoot("DiggThisConfig")]
        public class DiggThisPersistableProperties
        {
            #region Fields
            private string topic;
            private string bkgColor;
            private bool compact;
            private Alignment textWrapping;
            private bool customMargins;
            private int topMargin;
            private int rightMargin;
            private int bottomMargin;
            private int leftMargin;
            #endregion Fields

            #region Properties
            public string Topic
            {
                get { return topic; }
                set { topic = value; }
            }
            public string BkgColor
            {
                get { return bkgColor; }
                set { bkgColor = value; }
            }
            public bool Compact
            {
                get { return compact; }
                set { compact = value; }
            }
            public Alignment TextWrapping
            {
                get { return textWrapping; }
                set { textWrapping = value; }
            }
            public bool CustomMargins
            {
                get { return customMargins; }
                set { customMargins = value; }
            }
            public int TopMargin
            {
                get { return topMargin; }
                set { topMargin = value; }
            }
            public int RightMargin
            {
                get { return rightMargin; }
                set { rightMargin = value; }
            }
            public int BottomMargin
            {
                get { return bottomMargin; }
                set { bottomMargin = value; }
            }
            public int LeftMargin
            {
                get { return leftMargin; }
                set { leftMargin = value; }
            }
            #endregion Properties

            #region Initialization
            public DiggThisPersistableProperties()
            {
            }
            public DiggThisPersistableProperties(DiggThisConfig settings)
            {
                FromDiggThisSettings(settings);
            }
            #endregion Initialization

            #region Operations
            public void FromDiggThisSettings(DiggThisConfig settings)
            {
                Topic = settings.Topic;
                BkgColor = settings.BkgColor;
                Compact = settings.Compact;
                TextWrapping = settings.TextWrapping;
                CustomMargins = settings.CustomMargins;
                TopMargin = settings.TopMargin;
                RightMargin = settings.RightMargin;
                BottomMargin = settings.BottomMargin;
                LeftMargin = settings.LeftMargin;
            }
            public void ToDiggThisSettings(ref DiggThisConfig settings)
            {
                settings.Topic = Topic;
                settings.BkgColor = BkgColor;
                settings.Compact = Compact;
                settings.TextWrapping = TextWrapping;
                settings.CustomMargins = CustomMargins;
                settings.TopMargin = TopMargin;
                settings.RightMargin = RightMargin;
                settings.BottomMargin = BottomMargin;
                settings.LeftMargin = LeftMargin;
            }
            #endregion Operations
        }
        #endregion Internal Classes
    }
}